﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TSMR01Xml
{
    public partial class SettingForm : Form
    {


        public SettingForm()
        {
            InitializeComponent();

            comboBox1.Items.Add("设置模式");
            comboBox1.Items.Add("正常模式");
            comboBox1.Items.Add("升级模式");
            comboBox1.SelectedIndex = 0;
            SetTime();
            StartPosition = FormStartPosition.CenterScreen;
        }

        /// <summary>
        /// 设置服务端ip
        /// </summary>
        /// <param name="str"></param>
        public void ShowServerIp(string str)
        {
            serverIpText.Text = str;
        }
        /// <summary>
        /// 设置服务端port
        /// </summary>
        /// <param name="str"></param>
        public void ShowServerIpPort(string str)
        {
            serverPortText.Text = str;
        }       

        /// <summary>
        /// 设置IP等信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SetIpAddressClicl(object sender, EventArgs e)
        {
            if (MessageBox.Show("是否确认？", "确认设置IP参数", MessageBoxButtons.YesNo) != DialogResult.Yes)
            {
              return;
            }
            if (!IPCheck(this.txbIP.Text))
            {
                MessageBox.Show("ip地址Client不正确！");
                return;
            }
            if (!int.TryParse(this.txbPort.Text, out int ipPort))
            {
                MessageBox.Show("端口Client不正确！");
                return;
            }
            if (!IPCheck(this.serverIpText.Text))
            {
                MessageBox.Show("ip地址Server不正确！");
                return;
            }
            if (!int.TryParse(this.serverPortText.Text, out int serveripPort))
            {
                MessageBox.Show("端口Server不正确！");
                return;
            }
            if (!IPCheck(this.txbGateway.Text))
            {
                MessageBox.Show("网关不正确！");
                return;
            }
            if (!IPCheck(this.txbSubnetMask.Text))
            {
                MessageBox.Show("子网掩码不正确！");
                return;
            }

            byte[] data;
            List<byte> dataContent = new List<byte>();

            // 客户端
            byte[] ipData = new byte[4];
            string[] ips = this.txbIP.Text.Split('.');
            for (int i = 0; i < ips.Length; i++)
            {
                ipData[i] = Convert.ToByte(ips[i]);
            }
            dataContent.AddRange(ipData);


            int port = Convert.ToInt32(this.txbPort.Text);
            byte[] portData = new byte[4];
            portData = BitConverter.GetBytes(port).ToReverseByte();
            dataContent.AddRange(portData);

            // 服务端IP端口
            byte[] ipServerData = new byte[4];
            string[] ipssss = this.serverIpText.Text.Split('.');
            for (int i = 0; i < ipssss.Length; i++)
            {
                ipServerData[i] = Convert.ToByte(ipssss[i]);
            }
            dataContent.AddRange(ipServerData);


            int serverport = Convert.ToInt32(this.serverPortText.Text);
            byte[] serverportData = new byte[4];
            serverportData = BitConverter.GetBytes(serverport).ToReverseByte();
            dataContent.AddRange(serverportData);

            // 网关
            //string gateWay = this.txbGateway.Text;
            byte[] gateWayData = new byte[4];
            string[] gateWays = this.txbGateway.Text.Split('.');
            for (int i = 0; i < gateWays.Length; i++)
            {
                gateWayData[i] = Convert.ToByte(gateWays[i]);
            }
            dataContent.AddRange(gateWayData);

            // 子网掩码
            //string subnetMask = this.txbSubnetMask.Text;
            byte[] subnetMaskData = new byte[4];
            string[] subnetMaskDatas = this.txbSubnetMask.Text.Split('.');
            for (int i = 0; i < subnetMaskDatas.Length; i++)
            {
                subnetMaskData[i] = Convert.ToByte(subnetMaskDatas[i]);
            }
            dataContent.AddRange(subnetMaskData);


            data = GetSendData(dataContent.ToArray(), 0x8A);
            Form1.xmlTcpServerEntity.curentTcp.Client.Send(data);
        }

        /// <summary>
        /// 设置卡口RTC时间信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SetCardClick(object sender, EventArgs e)
        {
            #region 输入有效性验证

            if (string.IsNullOrEmpty(txbCarID.Text))
            {
                MessageBox.Show("卡口编号必须填写！");
                return;
            }
            if (string.IsNullOrEmpty(txbCamID.Text))
            {
                MessageBox.Show("卡口相机编号必须填写！");
                return;
            }

            #endregion

            List<byte> dta = new List<byte>();

            string kakou = txbCarID.Text;
            byte[] kakouData = new byte[32];
            for (int i = 0; i < kakou.Length; i++)
            {
                kakouData[i] = Encoding.ASCII.GetBytes(kakou[i].ToString()).FirstOrDefault();
            }            
            dta.AddRange(kakouData);//卡口编号

            string CamID = txbCamID.Text;
            byte[] CamIDData = new byte[32];
            for (int i = 0; i < CamID.Length; i++)
            {
                CamIDData[i] = Encoding.ASCII.GetBytes(CamID[i].ToString()).FirstOrDefault();
            }
            dta.AddRange(CamIDData);//相机卡口编号

            Form1.xmlTcpServerEntity.curentTcp.Client.Send(GetSendData(dta.ToArray(), 0x88));

        }

      

        // <summary>
        /// 正规则试验IP地址
        /// </summary>
        /// <param name="IP"></param>
        /// <returns></returns>
        public static bool IPCheck(string IP)
        {
            string num = @"((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))";
            return Regex.IsMatch(IP, num);
        }
        /// <summary>
        /// RTC时间设置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SetRctTimeClick(object sender, EventArgs e)
        {
            #region 有效性验证

            //// 年输入是否合法
            //if (!int.TryParse(this.txbYear.Text, out int yearOut))
            //{
            //    MessageBox.Show("年份格式不正确！");
            //    return;
            //}
            //// 月输入是否合法
            //if (!int.TryParse(this.txbMonth.Text, out int monthOut))
            //{
            //    MessageBox.Show("月份格式不正确！");
            //    return;
            //}
            //// 月输入是否合法
            //if (Convert.ToInt32(this.txbMonth.Text) < 0 || Convert.ToInt32(this.txbMonth.Text) > 12)
            //{
            //    MessageBox.Show("月份格式为1--12之间的数字！");
            //    return;
            //}
            //// 日输入是否合法
            //if (!int.TryParse(this.txbDay.Text, out int dayOut))
            //{
            //    MessageBox.Show("日格式不正确！");
            //    return;
            //}
            //// 时输入是否合法
            //if (!int.TryParse(this.txbHour.Text, out int hourOut))
            //{
            //    MessageBox.Show("小时格式不正确！");
            //    return;
            //}
            //// 分输入是否合法
            //if (!int.TryParse(this.txbMinute.Text, out int minOut))
            //{
            //    MessageBox.Show("分钟格式不正确！");
            //    return;
            //}
            //// 秒输入是否合法
            //if (!int.TryParse(this.txbSecond.Text, out int secondOut))
            //{
            //    MessageBox.Show("分钟格式不正确！");
            //    return;
            //}
            //// 毫秒输入是否合法
            //if (!int.TryParse(this.txbMS.Text, out int msOut))
            //{
            //    MessageBox.Show("毫秒格式不正确！");
            //    return;
            //}

            #endregion

            //List<byte> dta = new List<byte>();

            //Int16 year = Convert.ToInt16(txbYear.Text);
            //byte[] yearData = new byte[2];
            //yearData = BitConverter.GetBytes(year).ToReverseByte();
            //dta.AddRange(yearData);//年
            //dta.Add(Convert.ToByte(txbMonth.Text));//月
            //dta.Add(Convert.ToByte(txbDay.Text));//日
            //dta.Add(Convert.ToByte(txbHour.Text));//时
            //dta.Add(Convert.ToByte(txbMinute.Text));//分
            //dta.Add(Convert.ToByte(txbSecond.Text));//秒
            //Int16 ms = Convert.ToInt16(txbMS.Text);
            //byte[] msData = new byte[2];
            //msData = BitConverter.GetBytes(ms).ToReverseByte();
            //dta.AddRange(msData);//毫秒

            //Form1.xmlTcpServerEntity.curentTcp.Client.Send(GetSendData(dta.ToArray(), 0x8C));

            //改为直接发送当前系统时间
            List<byte> dta = new List<byte>();
            string strDateTime = DateTime.Now.ToString("yyyyMMddHHmmssfff");           
            Int16 year = Convert.ToInt16(strDateTime.Substring(0,4));
            byte[] yearData = new Byte[2];
            yearData = BitConverter.GetBytes(year).ToReverseByte();
            dta.AddRange(yearData);//年
            this.txbYear.Text = strDateTime.Substring(0, 4); ;
            dta.Add(Convert.ToByte(strDateTime.Substring(4, 2)));//月
            this.txbMonth.Text = strDateTime.Substring(4, 2);
            dta.Add(Convert.ToByte(strDateTime.Substring(6, 2)));//日
            this.txbDay.Text = strDateTime.Substring(6, 2);
            dta.Add(Convert.ToByte(strDateTime.Substring(8, 2)));//时
            this.txbHour.Text = strDateTime.Substring(8, 2);
            dta.Add(Convert.ToByte(strDateTime.Substring(10, 2)));//分
            this.txbMinute.Text = strDateTime.Substring(10, 2);
            dta.Add(Convert.ToByte(strDateTime.Substring(12, 2)));//秒
            this.txbSecond.Text = strDateTime.Substring(12, 2);
            Int16 ms = Convert.ToInt16(strDateTime.Substring(14, 3));
            byte[] msdData = new byte[2];
            msdData = BitConverter.GetBytes(ms).ToReverseByte();
            this.txbMS.Text = strDateTime.Substring(14, 3);
            dta.AddRange(msdData);//毫秒
            Form1.xmlTcpServerEntity.curentTcp.Client.Send(GetSendData(dta.ToArray(), 0x8C));
        }


        private void SetTime()
        {
            string strDateTime = DateTime.Now.ToString("yyyyMMddHHmmssfff");
            Int16 year = Convert.ToInt16(strDateTime.Substring(0, 4));
            byte[] yearData = new Byte[2];
            yearData = BitConverter.GetBytes(year).ToReverseByte();
            this.txbYear.Text = strDateTime.Substring(0, 4); ;
            this.txbMonth.Text = strDateTime.Substring(4, 2);
            this.txbDay.Text = strDateTime.Substring(6, 2);
            this.txbHour.Text = strDateTime.Substring(8, 2);
            this.txbMinute.Text = strDateTime.Substring(10, 2);
            this.txbSecond.Text = strDateTime.Substring(12, 2);
            Int16 ms = Convert.ToInt16(strDateTime.Substring(14, 3));
            byte[] msdData = new byte[2];
            msdData = BitConverter.GetBytes(ms).ToReverseByte();
            this.txbMS.Text = strDateTime.Substring(14, 3);
        }



        #region 获取下发数据

        /// <summary>
        /// 获取完全组包好的需要下发的数据
        /// BitConverter.GetBytes方法获得的数据是高字节在后，低字节在前
        /// </summary>
        /// <param name="data">消息体内容</param>
        /// <param name="msgType">消息类型</param>
        /// <returns></returns>
        private byte[] GetSendData(byte[] data, byte msgType)
        {
            if (data == null || data.Length < 1) throw new ArgumentException("消息体为空或者数据长度不足1个字节");

            //byte[] sendData = new byte[8 + 1 + 4 + 4 + data.Length + 2 + 8];

            List<byte> sendData = new List<byte>();

            // 包头
            sendData.AddRange(header);

            // 消息类型
            sendData.Add(msgType);

            // 序列号 自增
            int xuliehao = 0;
            sendData.AddRange(BitConverter.GetBytes(xuliehao).ToReverseByte());

            // 数据长度
            sendData.AddRange(BitConverter.GetBytes(data.Length).ToReverseByte());

            // 数据
            sendData.AddRange(data);

            // 校验码
            //Int16 crc = 0;
            //sendData.AddRange(BitConverter.GetBytes(crc).ToReverseByte());
            List<Byte> CheckCodeData = new List<byte>();
            CheckCodeData.Add(msgType);
            CheckCodeData.AddRange(BitConverter.GetBytes(xuliehao).ToReverseByte());
            CheckCodeData.AddRange(BitConverter.GetBytes(data.Length).ToReverseByte());
            CheckCodeData.AddRange(data);
            sendData.AddRange(Crc16_CCITT(CheckCodeData.ToArray())); 
            

            // 包尾
            sendData.AddRange(ender);

            return sendData.ToArray();
        }
        private byte[] header = new byte[8] { 0xAA, 0x1F, 0x2E, 0x3D, 0x4C, 0x5B, 0x6A, 0x55 };
        private byte[] ender = new byte[8] { 0x55, 0xA6, 0xB5, 0xC4, 0xD3, 0xE2, 0xF1, 0xAA };


        #endregion

        /// <summary>
        /// CRC校验码 16位_CCITT
        /// </summary>
        /// <param name="cmd">数据包含CRC校验码</param>
        /// <returns>crc校验码</returns>
        public static byte[] Crc16_CCITT(byte[] cmd)
        {
            if (cmd is null)
            {
                throw new ArgumentNullException(nameof(cmd));
            }

            int len = cmd.Length;
            int xda, xdapoly;
            int i, j, xdabit;
            xda = 0x0000;
            xdapoly = 0x8408;
            for (i = 0; i < len; i++)
            {
                xda ^= cmd[i];
                for (j = 0; j < 8; j++)
                {
                    xdabit = (int)(xda & 0x01);
                    xda >>= 1;
                    if (xdabit == 1)
                        xda ^= xdapoly;
                }
            }
            byte[] temp = new byte[2];
            temp[0] = (byte)(xda >> 8);
            temp[1] = (byte)(xda & 0xFF);
            return temp;
        }

        /// <summary>
        /// 判断CRC16是否相等
        /// </summary>
        /// <param name="cmd">数据</param>
        /// <param name="crc16">CRC</param>
        /// <returns></returns>
        public static bool IsSameCrc16(byte[] cmd, byte[] crc16)
        {
            if (cmd is null | crc16 is null)
            {
                throw new ArgumentNullException(nameof(cmd));
            }

            byte[] newcrc = Crc16_CCITT(cmd);

            for (int i = 0; i < 2; i++)
            {
                if (newcrc[i] != crc16[i])
                {
                    return false;
                }
            }
            return true;

        }
        /// <summary>
        /// 模式切换
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnArm_Click(object sender, EventArgs e)
        {
            var selectItem =this.comboBox1.SelectedItem;
            byte[] data;
            try
            {
                switch (selectItem.ToString())
                {
                    case "设置模式":
                        data = GetSendData(new byte[] { 0x0A }, 0x8E);
                        Form1.xmlTcpServerEntity.curentTcp.Client.Send(data);
                        break;
                    case "正常模式":
                        data = GetSendData(new byte[] { 0x05 }, 0x8E);
                        Form1.xmlTcpServerEntity.curentTcp.Client.Send(data);
                        break;
                    case "升级模式":
                        data = GetSendData(new byte[] { 0xAA }, 0x8E);
                        Form1.xmlTcpServerEntity.curentTcp.Client.Send(data);
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.Message);
            }

            // 直接下发
        }

        private void SettingForm_Load(object sender, EventArgs e)
        {
            Timer timer = new Timer();
            timer.Interval = 1000;
            timer.Enabled = true;
            timer.Tick += Timer_Tick;
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            this.txbTime.Text = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss:fff");
            //定时器中 显示客户端ip和端口
            this.txbIP.Text = Form1.clientIp;
            this.txbPort.Text = Form1.clientPort;
        }
    }
    public static class BytesInfoClass
    {
        /// <summary>
        /// 字节高低位调换【扩展方法】
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static byte[] ToReverseByte(this byte[] source)
        {
            byte[] result = new byte[source.Length];
            for (int i = 0; i < source.Length; i++)
            {
                result[source.Length - 1 - i] = source[i];
            }
            return result;
        }

    }


}
